﻿using FineUICoreDesigner.Base;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace FineUICoreDesigner
{
    public static class BaseHelp
    {
        #region 常量

        /// <summary>
        /// 配置
        /// </summary>
        public static DesignerConfig Config { get; set; } = new DesignerConfig()
        {
            //LogLevel = "1",
        };

        /// <summary>
        /// 当前空间的GUID
        /// </summary>
        public const string PackageGuidString = "f65a3614-da29-4c5f-8e46-802d23a3b65b";

        /// <summary>
        /// 窗口的GUID
        /// </summary>
        public const string GuidCodeMaidOutputPane = "4E269BCF-178A-4B09-A4B9-C3B97456F795";

        /// <summary>
        /// 不生成的标识
        /// </summary>
        public const string NoFineUIDesigner = "NoFineUIDesigner";

        /// <summary>
        /// 日志窗口
        /// </summary>
        public static IVsOutputWindowPane CodeMaidOutputWindowPane => GetCodeMaidOutputWindowPane();

        /// <summary>
        /// 输出日志
        /// </summary>
        public static Action<string> OutputLine = (msg) => BaseHelp.CodeMaidOutputWindowPane?.OutputString(msg + "\n");

        /// <summary>
        /// 配置信息
        /// </summary>
        public static JObject Appsetting { get; set; }

        #endregion 常量

        #region 公共方法

        /// <summary>
        /// 可能出现中文乱码所以用此方法
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static string GetCode(string filePath)
        {
            var code = File.ReadAllText(filePath);
            if (code.Contains("�")) // 检查是否有乱码字符
            {
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                code = File.ReadAllText(filePath, Encoding.GetEncoding("GBK"));
            }
            return code;
        }

        /// <summary>
        /// 写入替换文件，这里需要解析编码 <br/> 如果文件不存在就创建
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="fileContent"></param>
        public static void WriteAllText(string filePath, string fileContent)
        {
            //如果文件不存在就创建
            if (!File.Exists(filePath))
            {
                File.WriteAllText(filePath, fileContent);
                return;
            }
            // 指定要使用的编码格式
            Func<Encoding> GetFileEncoding = () =>
            {
                using (var reader = new StreamReader(filePath, true))
                {
                    reader.Peek(); // 读取文件的编码格式
                    return reader.CurrentEncoding;
                };
            };
            Encoding originalEncoding = GetFileEncoding();
            // 使用原始编码格式写入文件
            using (StreamWriter writer = new StreamWriter(
                filePath, false, originalEncoding))
            {
                writer.Write(fileContent);
            }
        }

        /// <summary>
        /// 重置配置信息
        /// </summary>
        /// <param name="solutionDirectory"></param>
        public static void InitConfig(IVsSolution solution)
        {
            try
            {
                var solutionDirectory = GetSolutionDirectory(solution);
                if (!string.IsNullOrEmpty(solutionDirectory))
                {
                    //string configFilePath = FindConfigFile(solutionDirectory, ".designerconfig");
                    //if (!string.IsNullOrEmpty(configFilePath))
                    //{
                    //    string jsonContent = File.ReadAllText(configFilePath);
                    //    var config = JsonConvert.DeserializeObject<DesignerConfig>(jsonContent);
                    //    BaseHelp.Config = config;
                    //    BaseHelp.OutputLine($"检测到配置文件: {config}");
                    //}
                    var projectPath = GetProjectPath(solution);
                    var isWebForms = GetEnableWebFormsConfigValue(projectPath);
                    BaseHelp.Config = new DesignerConfig()
                    {
                        ProjectPath = projectPath,
                        SolutionPath = solutionDirectory
                    };
                    BaseHelp.OutputLine("没想好的FineUIDesigner助手，启动成功✨");
                    BaseHelp.OutputLine($"读取到配置文件: {JObject.FromObject(BaseHelp.Config).ToString()}");
                }
            }
            catch { }
        }

        public static JObject GetConfigValue(IVsHierarchy hierarchy)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            if (hierarchy is IVsProject project)
            {
                project.GetMkDocument(VSConstants.VSITEMID_ROOT, out string projectPath);
                string projectDirectory = System.IO.Path.GetDirectoryName(projectPath);

                string appSettingsPath = System.IO.Path.Combine(projectDirectory, "appsettings.json");
                if (System.IO.File.Exists(appSettingsPath))
                {
                    string appSettingsContent = File.ReadAllText(appSettingsPath);
                    JObject jsonObject = JObject.Parse(appSettingsContent);
                    Appsetting = jsonObject;
                    return jsonObject;
                }
            }

            return new JObject();
        }

        public static bool GetEnableWebFormsConfigValue(JObject jsonObject)
        {
            JToken enableWebFormsValue = jsonObject.SelectToken("FineUI.EnableWebForms");
            if (enableWebFormsValue == null)
            {
                return false; // 如果没有找到EnableWebForms节点，则返回false
            }
            else
            {
                return enableWebFormsValue.Value<bool>();
            }
        }

        public static bool GetFineUIDesignerConfigValue(JObject jsonObject)
        {
            JToken DesignerValue1 = jsonObject.SelectToken("FineUI.FineUIDesigner");
            JToken DesignerValue2 = jsonObject.SelectToken("FineUIDesigner");
            if (DesignerValue1 == null && DesignerValue2 == null)
            {
                return true; // 如果没有找到FineUIDesigner节点，则返回false
            }
            else if (DesignerValue1 != null)
            {
                return DesignerValue1.Value<bool>();
            }
            else
            {
                return DesignerValue2.Value<bool>();
            }
        }

        #endregion 公共方法

        #region 静态私有方法

        private static JObject GetConfigValue(string projectPath)
        {
            string appSettingsPath = Path.Combine(projectPath, "appsettings.json");
            if (File.Exists(appSettingsPath))
            {
                string appSettingsContent = File.ReadAllText(appSettingsPath);
                JObject jsonObject = JObject.Parse(appSettingsContent);
                return jsonObject;
            }
            return new JObject();
        }

        private static bool GetEnableWebFormsConfigValue(string projectPath)
        {
            if (File.Exists(projectPath))
            {
                JObject jsonObject = GetConfigValue(projectPath);

                JToken enableWebFormsValue = jsonObject.SelectToken("FineUI.EnableWebForms");
                if (enableWebFormsValue == null)
                {
                    return false; // 如果没有找到EnableWebForms节点，则返回false
                }
                else
                {
                    return enableWebFormsValue.Value<bool>();
                }
            }
            return false;
        }

        /// <summary>
        /// 当前项目的路径
        /// </summary>
        /// <param name="hierarchy"></param>
        /// <returns></returns>
        private static string GetProjectPath(IVsHierarchy hierarchy)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            object propertyValue;
            hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out propertyValue);
            EnvDTE.Project project = propertyValue as EnvDTE.Project;
            return Path.GetDirectoryName(project.FullName);
        }

        private static string GetSolutionDirectory(IVsSolution solution)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            solution.GetSolutionInfo(out string solutionDirectory, out _, out _);
            return solutionDirectory;
        }

        private static string GetProjectPath(IVsSolution solution)
        {
            if (solution != null)
            {
                IVsHierarchy hierarchy;
                var itemId = solution.GetProjectOfUniqueName(GetSolutionDirectory(solution), out hierarchy);
                if (hierarchy == null)
                {
                    hierarchy = GetActiveProjectHierarchy();
                }
                if (hierarchy != null)
                {
                    string projectPath = GetProjectPath(hierarchy);
                    return projectPath;
                }
            }
            return string.Empty;
        }

        private static IVsHierarchy GetActiveProjectHierarchy()
        {
            IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
            monitorSelection.GetCurrentSelection(out IntPtr hierarchyPtr, out uint itemid, out IVsMultiItemSelect multiItemSelect, out IntPtr selectionContainer);

            if (hierarchyPtr == IntPtr.Zero)
            {
                return null;
            }

            IVsHierarchy hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy;
            Marshal.Release(hierarchyPtr);
            return hierarchy;
        }

        /// <summary>
        /// 日志窗口
        /// </summary>
        /// <returns></returns>
        private static IVsOutputWindowPane GetCodeMaidOutputWindowPane()
        {
            if (!(Package.GetGlobalService(typeof(SVsOutputWindow)) is IVsOutputWindow outputWindow))
            {
                return null;
            }

            Guid outputPaneGuid = new Guid(GuidCodeMaidOutputPane);

            outputWindow.CreatePane(ref outputPaneGuid, "FineUIDesigner生成日志", 1, 1);
            outputWindow.GetPane(ref outputPaneGuid, out IVsOutputWindowPane windowPane);

            return windowPane;
        }

        private static string FindConfigFile(string directory, string fileName)
        {
            foreach (var file in Directory.GetFiles(directory, fileName, SearchOption.AllDirectories))
            {
                return file;
            }
            return null;
        }

        #endregion 静态私有方法
    }
}
